package com.mstore.action;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.RenderingHints;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.labels.StandardPieToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.general.DefaultPieDataset;

import com.mstore.enumpackage.JFreeChartEnum;
import com.mstore.pojo.Account;
import com.mstore.service.AccountService;

public class JFreeChartAction extends BaseAction {

	private static final long serialVersionUID = -4911121358865226637L;

	private JFreeChart chart;// 这里变量名必须是chart，不能是其他变量名

	private JFreeChartEnum chartType;

	private AccountService accountService;

	/**
	 * 标题字体尺寸
	 */
	private int TitleFontSize = 20;

	/**
	 * 标签字体尺寸
	 */
	private int LabelFontSize = 10;

	/**
	 * 图例说明字体尺寸
	 */
	private int LegendFontSize = 15;

	public String executeChart() {
		switch (chartType) {
			case AccountBalanceChart:
				getAccountBalanceChart();
				break;
			case AccountMemberChart:
				getAccountMemberChart();
				break;
			case AccountInMonthChart:
				getAccountInMonth();
				break;
		}
		return SUCCESS;
	}

	// 生成大图 1024 * 768
	public String executeBigChart() {
		TitleFontSize = 25;
		LabelFontSize = 16;
		LegendFontSize = 20;
		switch (chartType) {
			case AccountBalanceChart:
				getAccountBalanceChart();
				break;
			case AccountMemberChart:
				getAccountMemberChart();
				break;
			case AccountInMonthChart:
				getAccountInMonth();
				break;
		}
		return "BigChart";
	}

	// 跳转到大图页面
	public String goToBigChart() {
		return "goToBigChart";
	}

	// 企业实时余额饼图
	private void getAccountBalanceChart() {
		// 创建饼图数据对象
		DefaultPieDataset dfp = new DefaultPieDataset();

		List<Account> accounts = accountService.getAccountsHasRbalance();

		for (Account account : accounts) {
			dfp.setValue(account.getName(), account.getRbalance());
		}

		// createpieChart创建饼图
		chart = ChartFactory.createPieChart(chartType.toString(), dfp, true,
				true, false);
		// 标题字体
		chart.setTitle(new TextTitle(chartType.toString(), new Font("宋体",
				Font.BOLD, TitleFontSize)));
		// 图片背景色
		chart.setBackgroundPaint(Color.WHITE);
		// 取得饼图plot对象
		PiePlot plot = (PiePlot) chart.getPlot();
		// 图形边框颜色
		// plot.setBaseSectionOutlinePaint(Color.RED);
		// plot.setBaseSectionPaint(Color.WHITE);
		// 图形边框粗细
		plot.setBaseSectionOutlineStroke(new BasicStroke(1.0f));

		// 指定图片的透明度(0.0-1.0)
		plot.setForegroundAlpha(0.65f);
		// 指定显示的饼图上圆形(true)还是椭圆形(false)
		plot.setCircular(true);

		// 设置第一个 饼块section 的开始位置，默认是12点钟方向
		// plot.setStartAngle(360);
		// 设置鼠标悬停提示
		// plot.setToolTipGenerator(new StandardPieToolTipGenerator());

		// 无数据时显示
		if (accounts.isEmpty()) {
			plot.setNoDataMessage("无数据!");
			plot.setNoDataMessagePaint(Color.red);
		}
		else {
			// 设置突出显示的数据块,这里固定设为第2个
			for (int i = 0; i < accounts.size(); i++) {
				if (i == 1) {
					plot.setExplodePercent(accounts.get(i).getName(), 0.1D);
					break;
				}
			}
		}

		String unitSytle = "{0}={1}元({2})";

		plot.setToolTipGenerator(new StandardPieToolTipGenerator(unitSytle,
				NumberFormat.getNumberInstance(), new DecimalFormat("0.00%")));

		// 引出标签显示样式
		plot.setLabelGenerator(new StandardPieSectionLabelGenerator(unitSytle,
				NumberFormat.getNumberInstance(), new DecimalFormat("0.00%")));

		// 图例显示样式
		plot.setLegendLabelGenerator(new StandardPieSectionLabelGenerator(
				unitSytle, NumberFormat.getNumberInstance(), new DecimalFormat(
						"0.00%")));

		// 设置饼图各部分标签字体
		plot.setLabelFont(new Font("宋体", Font.ITALIC, LabelFontSize));

		// 设置柱图背景色（注意，系统取色的时候要使用16位的模式来查看颜色编码，这样比较准确）
		plot.setBackgroundPaint(new Color(255, 255, 204));

		// 设置图例说明Legend上的文字
		chart.getLegend().setItemFont(
				new Font("宋体", Font.PLAIN, LegendFontSize));
	}

	// 无觅企业会员分布饼图
	private void getAccountMemberChart() {

	}

	// 每月企业入驻数量柱状图
	private void getAccountInMonth() {
		List<Map<String, Object>> accounts = accountService
				.getAccountsInMonth();

		Calendar cal = Calendar.getInstance();// 使用日历类
		chart = ChartFactory.createBarChart(chartType.toString(),
				cal.get(Calendar.YEAR) + "年", "入驻量", getAccountInMonthDataset(accounts),
				PlotOrientation.VERTICAL, false, false, false);

		chart.setTextAntiAlias(false);
		chart.setBackgroundPaint(Color.white);

		// 获得图表区域对象
		CategoryPlot plot = chart.getCategoryPlot();

		if (accounts.isEmpty())
			plot.setNoDataMessage("没有数据！");

		// 设置横虚线可见
		plot.setRangeGridlinesVisible(true);
		// 虚线色彩
		plot.setRangeGridlinePaint(Color.gray);
		// 数据轴精度
		NumberAxis vn = (NumberAxis) plot.getRangeAxis();
		// vn.setAutoRangeIncludesZero(true);
		// DecimalFormat df = new DecimalFormat("#0");
		// 数据轴数据标签的显示格式
		// vn.setNumberFormatOverride(df);

		// x轴设置
		CategoryAxis domainAxis = plot.getDomainAxis();
		// 轴标题
		domainAxis.setLabelFont(new Font("SansSerif", Font.TRUETYPE_FONT,
				LabelFontSize));
		// 轴数值
		domainAxis.setTickLabelFont(new Font("SansSerif", Font.TRUETYPE_FONT,
				LabelFontSize));
		// Lable（Math.PI/3.0）度倾斜
		// domainAxis.setCategoryLabelPositions(CategoryLabelPositions
		// .createUpRotationLabelPositions(Math.PI / 3.0));
		// 横轴上的 Lable 是否完整显示

		domainAxis.setMaximumCategoryLabelWidthRatio(6.00f);
		// 设置距离图片左端距离
		domainAxis.setLowerMargin(0.1);
		// 设置距离图片右端距离
		domainAxis.setUpperMargin(0.1);
		// 设置 columnKey 是否间隔显示
		// domainAxis.setSkipCategoryLabelsToFit(true);
		plot.setDomainAxis(domainAxis);
		// 设置柱图背景色（注意，系统取色的时候要使用16位的模式来查看颜色编码，这样比较准确）
		plot.setBackgroundPaint(new Color(255, 255, 204));

		// y轴设置
		ValueAxis rangeAxis = plot.getRangeAxis();
		rangeAxis.setLabelFont(new Font("SansSerif", Font.TRUETYPE_FONT,
				LabelFontSize));
		rangeAxis.setTickLabelFont(new Font("SansSerif", Font.TRUETYPE_FONT,
				LabelFontSize));
		// 设置最高的一个 Item 与图片顶端的距离
		rangeAxis.setUpperMargin(0.15);
		// 设置最低的一个 Item 与图片底端的距离
		rangeAxis.setLowerMargin(0.15);
		plot.setRangeAxis(rangeAxis);

		// 解决中文乱码问题(关键)
		TextTitle textTitle = chart.getTitle();
		textTitle.setFont(new Font("黑体", Font.PLAIN, TitleFontSize));
		domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN,
				LabelFontSize));
		domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, LabelFontSize));
		vn.setTickLabelFont(new Font("sans-serif", Font.PLAIN, LabelFontSize));
		vn.setLabelFont(new Font("黑体", Font.PLAIN, LabelFontSize));

		BarRenderer renderer = new BarRenderer();
		// 设置柱子宽度
		renderer.setMaximumBarWidth(0.2);
		// 设置柱子高度
		renderer.setMinimumBarLength(0.2);
		// 设置柱子边框颜色
		renderer.setBaseOutlinePaint(Color.BLACK);
		// 设置柱子边框可见
		renderer.setDrawBarOutline(true);
		// // 设置柱的颜色
		renderer.setSeriesPaint(0, Color.decode("#8BBA00"));
		// 设置每个地区所包含的平行柱的之间距离
		renderer.setItemMargin(0.5);
		chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING,
				RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
		// 显示每个柱的数值，并修改该数值的字体属性
		renderer.setIncludeBaseInRange(true);
		renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
		renderer.setBaseItemLabelsVisible(true);
		plot.setRenderer(renderer);
		// 设置柱的透明度
		plot.setForegroundAlpha(1.0f);

		// 背景色 透明度
		plot.setBackgroundAlpha(0.5f);
	}

	private CategoryDataset getAccountInMonthDataset(
			List<Map<String, Object>> maps) {
		double[][] data = new double[1][maps.size()];
		for (int i = 0; i < maps.size(); i++) {
			Map<String, Object> map = maps.get(i);
			data[0][i] = (Integer) map.get(i + 1 + "");
		}

		String[] rowKeys = { "" };
		String[] columnKeys = new String[maps.size()];
		for (int i = 0; i < maps.size(); i++) {
			Map<String, Object> map = maps.get(i);
			for (Map.Entry<String, Object> entry : map.entrySet()) {
				columnKeys[i] = entry.getKey() + "月";
			}
		}
		return DatasetUtilities
				.createCategoryDataset(rowKeys, columnKeys, data);
	}

	// getChart()方法是必须的，setChart()可以不写.
	public JFreeChart getChart() {
		return chart;
	}

	public JFreeChartEnum getChartType() {
		return chartType;
	}

	public void setChartType(JFreeChartEnum chartType) {
		this.chartType = chartType;
	}

	public AccountService getAccountService() {
		return accountService;
	}

	public void setAccountService(AccountService accountService) {
		this.accountService = accountService;
	}
}
